<?php
/**
 * ElasticSearch
 */
namespace app\common\model;

use app\common\InstanceTrait;
use Elasticsearch\ClientBuilder;
use Elasticsearch\Common\Exceptions\Missing404Exception;

class ElasticSearchModel
{
    use InstanceTrait;

    private $_devConfig = [
        'sports_search_expert' => [
            'host' => '127.0.0.1',
            'port' => 9200,
            'index' => 'sports_search_expert'
        ],
        'sports_search_blog' => [
            'host' => '127.0.0.1',
            'port' => 9200,
            'index' => 'sports_search_blog'
        ]
    ];

    private $_prodConfig = [
        'sports_search_expert' => [
            'host' => '127.0.0.1',
            'port' => 9200,
            'index' => 'sports_search_expert'
        ],
        'sports_search_blog' => [
            'host' => '127.0.0.1',
            'port' => 9200,
            'index' => 'sports_search_blog'
        ],
    ];

    private $_config;
    private $_client;
    private $_error = false;

    public function __construct($key)
    {
        $this->_config = $this->_devConfig;
        if (env('APP_ENV') == 'prod') {
            $this->_config = $this->_prodConfig;
        }

        if (!array_key_exists($key, $this->_config)) {
            $this->_error = true;
            return;
        }

        $this->_config = $this->_config[$key];
        $hosts = [$this->_config['host'] . ':' . $this->_config['port']];
        $this->_client = ClientBuilder::create()->setHosts($hosts)->build();
    }

    /**
     * 插入数据
     *
     * data['type']
     * data['data']
     */
    public function addDoc($type, $data)
    {
        try {
            if ($this->_error) {
                throw new \Exception('配置错误');
            }
            if (!is_array($data)) {
                throw new \Exception('参数缺失');
            }

            $params = [
                'index' => $this->_config['index'],
                'type' => $type,
                'body' => $data,
            ];

            if (isset($data['id'])) {
                $params['id'] = $data['id'];
            }

            $this->_client->index($params);
            return ['code' => 0, 'msg' => '成功'];
        } catch (\Exception $exception) {
            \Log::error($exception);
            return ['code' => -1, 'msg' => $exception->getMessage()];
        }
    }

    /**
     * 查询数据
     */
    public function getDocById($type, $id)
    {
        try {
            if ($this->_error) {
                throw new \Exception('配置错误');
            }

            $params = [
                'index' => $this->_config['index'],
                'type' => $type,
                'id' => $id
            ];
            return ['code' => 0, 'msg' => '成功', 'data' => $this->_client->get($params)];
        } catch (Missing404Exception $exception) {
            return ['code' => 0, 'data' => []];
        } catch (\Exception $exception) {
            \Log::error($exception);
            return ['code' => -1, 'msg' => $exception->getMessage()];
        }
    }

    /**
     * 根据ID更新数据
     */
    public function updateDoc($type, $id, $data)
    {
        try {
            if ($this->_error) {
                throw new \Exception('配置错误');
            }

            $params = [
                'index' => $this->_config['index'],
                'type' => $type,
                'id' => $id,
                'body' => ['doc' => $data]
            ];

            return ['code' => 0, 'msg' => '成功', 'data' => $this->_client->update($params)];
        } catch (\Exception $exception) {
            \Log::error($exception);
            return ['code' => -1, 'msg' => $exception->getMessage()];
        }
    }

    /**
     * 搜索
     */
    public function searchDoc($type, $body, $page = 1, $size = 10)
    {
        try {
            if ($this->_error) {
                throw new \Exception('配置错误');
            }

            $params = [
                'index' => $this->_config['index'],
                'type' => $type,
                'body' => $body,
                'from' => ($page - 1) * $size,
                'size' => $size
            ];

            $data = $this->_client->search($params);
            $hits = isset($data['hits']) ? $data['hits'] : [];
            $total = isset($hits['total']) ? $hits['total'] : 0;
            $hitsArr = isset($hits['hits']) ? $hits['hits'] : [];
            $list = [];
            foreach ($hitsArr as $value) {
                $list[] = $value['_source'];
            }

            $return = [
                'total' => $total,
                'list' => $list
            ];
            return ['code' => 0, 'msg' => '成功', 'data' => $return];
        } catch (\Exception $exception) {
            \Log::error($exception);
            return ['code' => -1, 'msg' => '暂无数据', 'data' => []];
        }
    }
}
